package org.example;

import java.util.*;
import java.util.stream.Collectors;
import java.util.AbstractMap.SimpleImmutableEntry;

public class WordFrequencyAnalyzer {
    public static void main(String[] args) {
        String text = "Since 2016, this leading Philippine fiber broadband operator has built or leased nine \n" +
                "IDCs across Manila’s metropolitan area, a region with 12.9 million people and one of \n" +
                "the most densely populated cities in the world. The demand for data center services has \n" +
                "dramatically increased so much that Converge is already engaging in a new series of \n" +
                "major upgrades. As the company’s IDC services have been growing, customer demand has \n" +
                "grown even faster, with bandwidth demand increasing ten-fold in just two years, \n" +
                "straining legacy DCI systems. But given physical constraints, any new upgrades needed \n" +
                "to be carefully thought through. The physical footprint had to be kept to a minimum, \n" +
                "with hardware future- proofed to be match predicted increases in bandwidth demand. \n" +
                "Furthermore, rollout needed to be quick and efficient, and simplified Operations and \n" +
                "Maintenance (O&M) were a must, to minimize the risk of downtime.Converge looked to \n" +
                "implement upgrades that could be deployed quickly in order to maintain the company’s \n" +
                "reputation for high-speed, low latency services and network reliability. Following an \n" +
                "in-depth evaluation, it selected Huawei’s DC OptiX 2.0 Wavelength Division Multiplexing \n" +
                "(WDM) solution that, Brusola believes, is capable of handling the company’s burgeoning \n" +
                "IDC traffic not just right now, but for the next decade too";
        List<String> words =  Arrays.stream(text.toLowerCase()
                        .replaceAll("[^a-zA-Z\\s]", " ")
                        .replaceAll("\\s+", " ")
                        .trim()
                        .split("\\s+"))
                .filter(word -> !word.isEmpty())
                .collect(Collectors.toList());
        Map<String, Integer> wordFrequency = new HashMap<>();
        words.forEach(word -> wordFrequency.merge(word, 1, Integer::sum));
        Map<String, Map<String, Integer>> leftNeighbors = new HashMap<>();
        Map<String, Map<String, Integer>> rightNeighbors = new HashMap<>();
        for (int i = 0; i < words.size(); i++) {
            String current = words.get(i);
            if (i > 0) {
                String left = words.get(i - 1);
                leftNeighbors.computeIfAbsent(current, k -> new HashMap<>())
                        .merge(left, 1, Integer::sum);
            }
            if (i < words.size() - 1) {
                String right = words.get(i + 1);
                rightNeighbors.computeIfAbsent(current, k -> new HashMap<>())
                        .merge(right, 1, Integer::sum);
            }
        }
        List<Map.Entry<String, Integer>> sortedWords = wordFrequency.entrySet().stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue(Comparator.reverseOrder())
                        .thenComparing(Map.Entry.comparingByKey()))
                .collect(Collectors.toList());
        for (int i = 0; i < Math.min(3, sortedWords.size()); i++) {
            Map.Entry<String, Integer> entry = sortedWords.get(i);
            String word = entry.getKey();
            int freq = entry.getValue();
            SimpleImmutableEntry<String, Integer> left = getTopNeighbor(leftNeighbors.getOrDefault(word, Collections.emptyMap()));
            SimpleImmutableEntry<String, Integer> right = getTopNeighbor(rightNeighbors.getOrDefault(word, Collections.emptyMap()));
            System.out.printf("- %s %d, left: %s %d, right: %s %d%n",
                    word, freq,
                    left.getKey(), left.getValue(),
                    right.getKey(), right.getValue());
        }
    }
    private static SimpleImmutableEntry<String, Integer> getTopNeighbor(Map<String, Integer> neighbors) {
        return neighbors.entrySet().stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue(Comparator.reverseOrder())
                        .thenComparing(Map.Entry.comparingByKey()))
                .map(e -> new SimpleImmutableEntry<>(e.getKey(), e.getValue()))
                .findFirst()
                .orElse(new SimpleImmutableEntry<>("null", 0));
    }
}
